from typing import Any

from typing_inspect import get_args, is_union_type

from zkl_pyutils_serialization.basics import get_context_tag_value
from zkl_pyutils_serialization.convert import convert, registry
from zkl_pyutils_serialization.tags import DstTypehint


@registry.register({})
def union_dst_convertor(value: Any) -> Any:
    typehint = get_context_tag_value(DstTypehint)
    if is_union_type(typehint):
        variants = get_args(typehint)
    elif isinstance(typehint, tuple):
        variants = typehint
    else:
        raise NotImplementedError

    variants_error = []
    for variant in variants:
        try:
            return convert(value, dst_typehint=variant)
        except Exception as error:
            variants_error.append(error)

    message = f"Failed to convert for all variants {variants}"
    raise NotImplementedErrorGroup(message, variants_error)


class NotImplementedErrorGroup(ExceptionGroup, NotImplementedError):
    pass
